#include "259macros.h"
#include "boing.h"
#define MAX_MBLOCKS 8
#define MAX_FBLOCKS 3
#define PADDLE_WIDTH 30
#define PADDLE_HEIGHT 5
#define BALL_DIAMETER 4
#define BLOCK_WIDTH 30
#define BLOCK_HEIGHT 5
#define LEFT_BORDER_HEIGHT 240
#define LEFT_BORDER_WIDTH 40
#define TOP_BORDER_HEIGHT 5
#define TOP_BORDER_WIDTH 320
#define BOTTOM_BORDER_HEIGTH 5
#define RIGHT_BORDER_HEIGHT 240
#define RIGHT_BORDER_WIDTH 40


#define TRUE 1
#define FALSE 0
int score = 0;
int mobileboxOnScreen = MAX_MBLOCKS; 
int scale = 2;
int rightwall = FALSE;
int leftwall = FALSE;
int topwall = FALSE;
int livesRemaining = 3;
int boingEnd = sizeof( boing );
int hex7segNumbers[] = { DIGIT0, DIGIT1, DIGIT2, DIGIT3, DIGIT4, DIGIT5, DIGIT6, DIGIT7, DIGIT8, DIGIT9 };
int hex7segScore = 0;
char Welcome[] = { 'W', 'E', 'L', 'C', 'O' , 'M', 'E' };
char flipToStart[] = { 'F', 'L', 'I', 'P', ' ', 'S', 'W', '1', ' ' , 'T', 'O', ' ', 'B', 'E', 'G', 'I', 'N' };
char Win[] = { 'Y', 'O', 'U', ' ', 'W', 'I', 'N' };
char Lose[] = { 'Y', 'O', 'U', ' ', 'L', 'O', 'S', 'E' };
char Countdown[] = { '3', '2', '1', ' '};

/*
#define MAX_X_PIXELS    320
#define MAX_Y_PIXELS    240
*/


/* subroutines */ 
 struct Block{
                int x,y;
                int blockhit;
                unsigned short colour;
        };
                
                

        struct Ball{
                int x, xinit, y, yinit, vx, vy, vxinit, vyinit, vabs,bounce, count;
                unsigned short colour;
        };

        

        struct Paddle{
                int x,xinit,vx, vxabs, paddlehit;
                unsigned short colour;
        };

                struct Block mobileBlock[MAX_MBLOCKS];
        struct Block fixedBlock[MAX_FBLOCKS]; 
                struct Paddle paddle;
                struct Ball ball;

        struct Block (*pmobileBlock)[MAX_MBLOCKS] = &mobileBlock;
        struct Block (*pfixedBlock)[MAX_FBLOCKS] = &fixedBlock;
                struct Ball* pball = &ball;
                struct Paddle* ppaddle = &paddle;


void playSound()
/* POST: plays a boing sound when invoked */
{
    int i;
    for( i = 0; i < boingEnd ; i++ )
    {
        //if (*pSNDRDY >> 24 == 0 )
        //{
            *pSNDL = (boing[i]/3) ;
            *pSNDR = (boing[i+1]/3) ;
            i++;
        //}
    }
}
void drawBlock( struct Block* pblock )
/* POST: draws a block specified by its center point (x,y) and
   with its specified colour */ 
{
        unsigned int ybound = pblock->y-(BLOCK_HEIGHT/2);
        unsigned int ystart = pblock->y+(BLOCK_HEIGHT/2);
        unsigned int xbound = pblock->x+(BLOCK_WIDTH/2);
        unsigned int xstart = pblock->x-(BLOCK_WIDTH/2);
        int x = 0, y = 0;
        for( x = xstart; x <= xbound; x++)
        {
                for(y = ystart; y >= ybound;y--)
                {       
                       drawPixel(x,y,pblock->colour);
                }
        }
}

void eraseBlock( struct Block* pblock, unsigned int ERASE )
/* POST: erases a block specified by its center point (x,y) */
{
        unsigned int ybound = pblock->y-(BLOCK_HEIGHT/2);
        unsigned int ystart = pblock->y+(BLOCK_HEIGHT/2);
        unsigned int xbound = pblock->x+(BLOCK_WIDTH/2);
        unsigned int xstart = pblock->x-(BLOCK_WIDTH/2);
        int x = 0, y = 0;
        for( x = xstart; x <= xbound; x++)
        {
                for(y = ystart; y >= ybound;y--)
                {       
                    drawPixel(x,y,ERASE);
                }
        }
        playSound();
}

void drawPaddle( struct Paddle* ppaddle )
{
                unsigned int ybound = MAX_Y_PIXELS-PADDLE_HEIGHT-BOTTOM_BORDER_HEIGTH;
        unsigned int ystart = MAX_Y_PIXELS-BOTTOM_BORDER_HEIGTH;
        unsigned int xbound = ppaddle->x+(PADDLE_WIDTH/2)+ppaddle->vxabs;
        unsigned int xstart = ppaddle->x-(PADDLE_WIDTH/2)-ppaddle->vxabs;
        int x = 0, y = 0;
        for( x = xstart; x <= xbound; x++)
        {
                for(y = ystart; y >= ybound;y--)
                {       
                        drawPixel(x,y,ppaddle->colour);
                }
        }

}

void drawBackground(void)
/* POST: draws a backgound which will remain fixed during gameplay */
{
        //draw left wall
        int xstart = 0;
        int xend = LEFT_BORDER_WIDTH;
        int ystart = MAX_Y_PIXELS;
        int yend = 0;
        int x, y;
        for( x = xstart; x < xend; x++ )
        {
                for( y = ystart; y > yend; y-- )
                {
                        drawPixel(x,y,makeColour(5,5, 5));
                }
        }

        xstart = 0;
        xend = MAX_X_PIXELS;
        ystart = MAX_Y_PIXELS;
        yend = MAX_Y_PIXELS - BOTTOM_BORDER_HEIGTH;

        for( y = ystart; y > yend; y-- )
        {
                for( x = xstart; x < xend; x++ )
                {
                        drawPixel(x,y,makeColour(5,5,5));
                }
        }

        xstart = MAX_X_PIXELS-RIGHT_BORDER_WIDTH;
        xend = MAX_X_PIXELS;
        ystart = MAX_Y_PIXELS;
        yend = 0;

        for( x = xstart; x < xend; x++ )
        {
                for( y = ystart; y > yend; y-- )
                {
                        drawPixel(x,y,makeColour(5,5, 5));
                }
        }

        xstart = 0;
        xend = MAX_X_PIXELS;
        ystart = TOP_BORDER_HEIGHT;
        yend = 0;

        for( y = ystart; y > yend; y-- )
        {
                for( x = xstart; x < xend; x++ )
                {
                        drawPixel(x,y,makeColour(5,5, 5));
                }
        }


}
void countDown()
/* POST: Initialize a countdown preparing the user to start again after losing a life */
{
    unsigned short BLACK   = makeColour(  0,  0,  0 );
    int i;
    if(livesRemaining)
    {
        for( i = 0; i < sizeof(Countdown); i++ )
        {
            drawChar( 20, 15, Countdown[i] );
            if( i < (sizeof(Countdown) - 1) )
                timedDelay( 1000* ONE_MS );
        }
    }
}

void menuScreen()
/* POST: Draws the menu screen where user must flip SW1 to begin playing */
{    
    unsigned short BLACK   = makeColour(  0,  0,  0 );
    int i;

    initScreen();
    fillScreen( BLACK );
    
    for( i = 0; i < sizeof(Welcome); i++ )
        drawChar( 15 + i , 5, Welcome[i] );

    for( i = 0; i < sizeof(flipToStart); i ++ )
        drawChar( 10 + i, 15, flipToStart[i] );

    if( *pSWITCH & 1 )
    {
        while( (*pSWITCH & 1) )
        {
        }
    }
    else if( !(*pSWITCH & 1 ) )
    {
        while(!(*pSWITCH & 1) )
        {
        }
    }
}

void resetBall( struct Ball* pball )
/* POST: resets the location of the ball to the center of the screen */
{
    unsigned short ERASE = makeColour( 0, 0 ,0 );
    int x = 0, y = 0;
    int xstart = pball->xinit-(BALL_DIAMETER/2);
    int xend = xstart+BALL_DIAMETER;
    int ystart = pball->yinit+(BALL_DIAMETER/2);
    int yend = ystart-BALL_DIAMETER;
    for( x=xstart; x<xend; x++ )
       {
           for( y = ystart; y>yend; y-- )
                drawPixel(x,y,ERASE);
        }
    
     pball->x = MAX_X_PIXELS/2;
     pball->y = MAX_Y_PIXELS/2;
     pball->xinit = pball->x;
     pball->yinit = pball->y;
     pball->vx = -1;
     pball->vy = 1;
     pball->vxinit = -1;
     pball->vyinit = 1;
     pball->vabs = 1;
     pball->bounce = 3;
     pball->count = 0;  
}

void initialize(struct Paddle* ppaddle,struct Block* pmobileBlock,struct Block* pfixedBlock,struct Ball* pball)
{
        /* defining Colours */

                unsigned short Acolour = makeColour(  0, 63,  0 );      /* bright green*/
                unsigned short Bcolour = makeColour( 63,  0, 63 );      /* bright magenta*/
                unsigned short Ccolour = makeColour( 30,  0, 63 );
                unsigned short Dcolour = makeColour( 30,  40, 63 );
                unsigned short Ecolour = makeColour( 0,  30, 63 );
                unsigned short Fcolour = makeColour( 50,  0, 30 );
                unsigned short Gcolour = makeColour( 64,  30, 0 );
                unsigned short Hcolour = makeColour( 20,  30, 50 );

                unsigned short RED     = makeColour( 63,  0,  0 );      /* bright red*/
                unsigned short BLACK   = makeColour(  0,  0,  0 );      /* black*/
        unsigned short grey    = makeColour(  40, 40,  40); /* invisible*/
                unsigned short grey1   = makeColour(  30 ,30,  30 );
        /*static const short ERASE = BLACK;*/
        /* define an array that stores all colours. will use this to initialize each box with a different colour */
        unsigned short colourarray[MAX_MBLOCKS] = {Acolour,Bcolour,Ccolour, Dcolour, Ecolour, Fcolour, Gcolour, Hcolour,};
                mobileboxOnScreen = MAX_MBLOCKS; 
                initScreen();
                fillScreen( BLACK );
        
        /* defining ball */
        pball->x = MAX_X_PIXELS/2;
        pball->y = MAX_Y_PIXELS/2;
        pball->xinit = pball->x;
        pball->yinit = pball->y;
        pball->vx = -1;
        pball->vy = 1;
                pball->vxinit = -1;
        pball->vyinit = 1;
                pball->vabs = 1;
                pball->bounce = 3;
                pball->count = 0;
        pball->colour = grey;

                int posx = (MAX_X_PIXELS - 2*LEFT_BORDER_WIDTH)/4;
                int posy = 70;
                int next = BLOCK_WIDTH+2;
        /*defining mobiBlocks and fixedBlocks */
        //int MlocationX[MAX_MBLOCKS]; //= {130,152,182,213,142,174,206,213}; /* for now (to test). Change later */
        //int MlocationY[MAX_MBLOCKS]; //= {70,70,70, 70, 64, 64, 64, 58}; /* for now (to test). Change later */

        int FlocationX[MAX_MBLOCKS] = {60,122,202}; /* for now (to test). Change later */
        int FlocationY[MAX_MBLOCKS] = {85,85,85}; /* for now (to test). Change later */
                
                
                /*  show all the colours....red/green/blue
                int red,green,blue;
                for( red = 0; red< 64; red++)
                        for( green = 0; green< 64; green++ )
                                for( blue = 0; blue<64; blue++)
                                        drawPixel(red,green,makeColour(red,green,blue));*/
        
        int i;
        for( i=0; i<MAX_FBLOCKS; i++)
        {
                pfixedBlock[i].x = FlocationX[i];
                pfixedBlock[i].y = FlocationY[i];
                pfixedBlock[i].colour = grey1;

                                drawBlock( &pfixedBlock[i] );
        }
                int j = 0;
        for( i=0; i<MAX_MBLOCKS; i++)
        {
                /*pmobileBlock[i].x = MlocationX[i];
                pmobileBlock[i].y = MlocationY[i];
                */
                        
                        pmobileBlock[i].x = posx;
                        posx += next;
                        pmobileBlock[i].y = posy;
                        pmobileBlock[i].colour = colourarray[i];
                        pmobileBlock[i].blockhit = FALSE;
                        drawBlock( &pmobileBlock[i] );
                        if( j == 4 )
                        {
                                posy -= BLOCK_HEIGHT+2;
                                posx = (MAX_X_PIXELS - 2*LEFT_BORDER_WIDTH)/4;
                                j = 0;
                        }
                        j++;
        }

        /* defining paddle */
        ppaddle->x = MAX_X_PIXELS/2;
        /*ppaddle->x = MAX_Y_PIXELS-(PADDLE_HEIGHT/2);*/
                ppaddle->vx = 3;
                ppaddle->vxabs = 3;
        ppaddle->colour = grey1; //for now (to test). change later
                ppaddle->paddlehit = FALSE;
                drawPaddle( ppaddle );
                drawBackground();

        
}
void drawBall( struct Ball* pball, unsigned int ERASE )
/* POST: Erases ball at previous location (xint, yint) and draws a ball at 
   new location (x,y) specified by the balls center. */
{
        int x = 0, y = 0;
        int xstart = pball->xinit-(BALL_DIAMETER/2);
        int xend = xstart+BALL_DIAMETER;
        int ystart = pball->yinit+(BALL_DIAMETER/2);
        int yend = ystart-BALL_DIAMETER;
        for( x=xstart; x<xend;x++)
        {
                for( y = ystart; y>yend; y--)
                        drawPixel(x,y,ERASE);
        }

        xstart = pball->x-(BALL_DIAMETER/2);
        xend = xstart+BALL_DIAMETER;
        ystart = pball->y+(BALL_DIAMETER/2);
        yend = ystart-BALL_DIAMETER;

        for( x=xstart; x<xend;x++)
        {
                for( y = ystart; y>yend; y--)
                        drawPixel(x,y,pball->colour);
        }
}






int collisionCheck_Block(struct Ball* pball, struct Block* pblock, struct Block* pfixedblock, struct Paddle* ppaddle)
/* POST: updates ball velocity if collided with a box and update blockhit variable
   Return: none */
{
        /* bool collisionCheck(int* pX, int* pY, int* vx, int* vy, Box* box) 
           collision(&ball.x,&ball.y,&ball.vx, &ball.vy, &colouredBoxes[i]) */
                int i;
        int* px = &pball->x;
        int* py = &pball->y;
        int* vx = &pball->vx;
        int* vy = &pball->vy;
                int collided = FALSE;
        int offset = 2;
        int case_ = -1;
                int RADIUS = BALL_DIAMETER/2;
        int RightBound  = pblock->x + (BLOCK_WIDTH/2);
        int LeftBound   = pblock->x - (BLOCK_WIDTH/2);
        int TopBound    = pblock->y - (BLOCK_HEIGHT/2);
        int BottomBound = pblock->y + (BLOCK_HEIGHT/2);

        if(*px > LeftBound && *px < RightBound && !pblock->blockhit)
        {
                if( *py > TopBound-5 && *py < BottomBound+5) /* Hit the top? */
                {
                                                pball->vyinit = pball->vy;
                        pball->vy *= -1;
                                                collided = TRUE;
                        pblock->blockhit = TRUE;
                }

        }
        else if(*py > TopBound && *py < BottomBound && !pblock->blockhit )
        {
                if( *px > LeftBound-5 && *px < RightBound+5 )/* Hit the left? */
                {
                                                pball->vxinit = pball->vx;
                        pball->vx *= -1;
                                                collided = TRUE;
                        pblock->blockhit = TRUE;
                }
        }

                if(collided){
                        
                        for( i = 0; i< MAX_FBLOCKS; i++)
                        {
                                if( pfixedblock[i].x == pblock->x && pfixedblock[i].y == pblock->y )continue;
                                pfixedblock[i].blockhit = FALSE;
                        }
                        pball->count = 0;
                        pball->bounce = 5;
                        ppaddle->paddlehit = FALSE;
                        rightwall = FALSE;
                        leftwall = FALSE;
                        topwall = FALSE;

                        if( pball->vx < 0 && pball->vx+1 != 0 && pball->vx+1 <= 4 )
                        {
                                pball->vx += 1;
                                return collided;
                        }
                        else if (pball->vx > 0 && pball->vx-1 != 0 && pball->vx-1 >= -4) 
                        {
                                pball->vx -= 1;
                                return collided;
                        }
                        if( pball->vy < 0 && pball->vy+1 != 0 && pball->vy+1 <= 4)
                        {
                                pball->vy += 1;
                                return collided;
                        }
                        else if(pball->vy > 0 && pball->vy-1 != 0 && pball->vy-1 >= -4) 
                        {
                                pball->vy -= 1;
                                return collided;
                        }
                }

                return collided;

}
void changeball_velocity(struct Ball* ball, struct Paddle* paddle)
{
        //int vx = 0;

        if( ball->vx >= paddle->vx )ball->vx += paddle->vx;
        else if( ball->vx <= paddle->vx )ball->vx += paddle->vx;
}

int collisionCheck_Paddle(struct Ball* ball, struct Paddle* paddle, struct Block* pfixedblock)
/* POST: updates ball velocity if collided with paddle 
  Return: none */
{
        int collided = FALSE;
        if( !paddle->paddlehit && ((ball->x - (BALL_DIAMETER/2)) <= (paddle->x + PADDLE_WIDTH/2) )
        &&(( ball->x - (BALL_DIAMETER/2)) >= (paddle->x - PADDLE_WIDTH/2))
        &&(ball->y >= MAX_Y_PIXELS-PADDLE_HEIGHT-BOTTOM_BORDER_HEIGTH-5) )
        {
                ball->vyinit = ball->vy;
                if( checkkey3() || checkkey2 () )
                {
                                ball->vx += paddle->vx;
                                if( ball->vy*ball->vy <= 9 ) ball->vy *= 2;
                }
                ball->vy *= -1;
                collided = TRUE;
        }

        else if( !paddle->paddlehit && ((ball->x + (BALL_DIAMETER/2)) <= (paddle->x + PADDLE_WIDTH/2) )
        &&(( ball->x + (BALL_DIAMETER/2)) >= (paddle->x - PADDLE_WIDTH/2))
        &&(ball->y >= MAX_Y_PIXELS-PADDLE_HEIGHT-BOTTOM_BORDER_HEIGTH-5))
        {
                ball->vyinit = ball->vy;
                if( checkkey3() || checkkey2 () ) 
                {
                                ball->vx += paddle->vx;
                                if( ball->vy*ball->vy <= 9 ) ball->vy *= 2;
                }
                ball->vy *= -1;
                collided = TRUE;
        }
        else if( !paddle->paddlehit && ((ball->x + (BALL_DIAMETER/2)) == (paddle->x - PADDLE_WIDTH/2) )
        &&(( ball->y + (BALL_DIAMETER/2)) >= MAX_Y_PIXELS-PADDLE_HEIGHT-5-BOTTOM_BORDER_HEIGTH))
        {
                ball->vx *= -1;
                ball->vy *= -1;
                collided = TRUE;
        }
        else if( !paddle->paddlehit && ((ball->x - (BALL_DIAMETER/2)) == (paddle->x + PADDLE_WIDTH/2) )
        &&(( ball->y + (BALL_DIAMETER/2)) >= MAX_Y_PIXELS-PADDLE_HEIGHT-BOTTOM_BORDER_HEIGTH-5))
        {
                ball->vx *= -1;
                ball->vy *= -1;
                collided = TRUE;
        }
        if(collided)
        {       int i;
                for( i = 0; i< MAX_FBLOCKS; i++)
                {                       
                        pfixedblock[i].blockhit = FALSE;
                }
                ball->count = 0;
                pball->bounce = 5;
                paddle->paddlehit = TRUE;
                rightwall = FALSE;
                leftwall = FALSE;
                topwall = FALSE;
        }
        return collided;
}


int collisionCheck_Walls(struct Ball* pball, struct Block* pfixedblock, struct Paddle* ppaddle)
/* POST: updates ball velocity if collided with walls
   Return: none */
{
        int collided = FALSE;
        unsigned short RED     = makeColour( 63,  0,  0 ); 
        unsigned short BLACK   = makeColour(  0,  0,  0 );
        /* collided with top wall*/
        if( !topwall && pball->y - (BALL_DIAMETER/2) < TOP_BORDER_HEIGHT+5 )            
        {
                pball->vyinit = pball->vy;
                pball->vy *= -1;
                topwall = TRUE;
                collided = TRUE;
        }
        
        /* collided with left wall?*/
    else if (!leftwall && pball->x - (BALL_DIAMETER/2) < LEFT_BORDER_WIDTH+5 ) 
        {
                pball->vxinit = pball->vx;
                pball->vx *= -1;
                leftwall = TRUE;
                collided = TRUE;
        }
        /* collided with right wall?*/
        else if (!rightwall && pball->x + (BALL_DIAMETER/2) > MAX_X_PIXELS-RIGHT_BORDER_WIDTH-5 ) 
        {
                pball->vxinit = pball->vx;
                pball->vx *= -1;
                rightwall = TRUE;
                collided = TRUE;
        }
        /*collided with bottom wall*/
        else if( pball->y + (BALL_DIAMETER/2) > MAX_Y_PIXELS-BOTTOM_BORDER_HEIGTH )
        {
               livesRemaining--;
               resetBall( &ball );
               countDown();
               

                
        }
        
        if(collided)
        {       int i;
                for( i = 0; i< MAX_FBLOCKS; i++)
                {
                                pfixedblock[i].blockhit = FALSE;
                }
                pball->count = 0;
                pball->bounce = 5;
                ppaddle->paddlehit = FALSE;

                if( pball->vx < 0 && pball->vx+1 != 0)
                        {
                                pball->vx += 1;
                                return collided;
                        }
                        else if (pball->vx > 0 && pball->vx-1 != 0) 
                        {
                                pball->vx -= 1;
                                return collided;
                        }
                        if( pball->vy < 0 && pball->vy+1 != 0)
                        {
                                pball->vy += 1;
                                return collided;
                        }
                        else if(pball->vy > 0 && pball->vy-1 != 0) 
                        {
                                pball->vy -= 1;
                                return collided;
                        }
        }
        return collided;
}

void movePaddle(struct Paddle* ppaddle,unsigned int ERASE)
/* POST: redraws the paddle in a new position if key 3 or key 2 are pressed
   Return: none */
{
        int starty = MAX_Y_PIXELS-BOTTOM_BORDER_HEIGTH;
        int boundy = starty-PADDLE_HEIGHT;
        int xdraw = 0;
        int xerase = 0;
        int y = 0, j = 0, moveleft = FALSE, moveright = FALSE;
        unsigned int refreshRate = 0;

        /*update position */
        //drawPaddle(ppaddle);
        ppaddle->xinit = ppaddle->x;
        if( (ppaddle->xinit-PADDLE_WIDTH/2-ppaddle->vxabs > LEFT_BORDER_WIDTH) && (checkkey3() ))
        {
                ppaddle->x += ppaddle->vx;
        }
                
        else if((ppaddle->xinit+PADDLE_WIDTH/2+ppaddle->vxabs < MAX_X_PIXELS-RIGHT_BORDER_WIDTH ) && (checkkey2()))
        {
                ppaddle->x += ppaddle->vx;
        }
        if( ppaddle->xinit > ppaddle->x ) /* did the paddle move left*/
        {
                xdraw = ppaddle->x-(PADDLE_WIDTH/2);
                xerase = ppaddle->xinit+(PADDLE_WIDTH/2)+ppaddle->vxabs;
                moveleft = TRUE;
        }
        else if ( ppaddle->xinit < ppaddle->x )/* did the paddle move right*/
        {
                xdraw = ppaddle->x+(PADDLE_WIDTH/2);
                xerase = ppaddle->xinit-(PADDLE_WIDTH/2)-ppaddle->vxabs;
                moveright = TRUE;
        }
        else
                return;

        refreshRate = ppaddle->vxabs;
        for( j = 0; j<refreshRate; j++)
        {
                for( y = starty; y >= boundy; y-- )
                {
                        if(moveright)
                        {
                                 drawPixel(xerase+j,y,ERASE);
                                 drawPixel(xdraw+j,y,ppaddle->colour);
                        }
                        else if(moveleft)
                        {
                                 drawPixel(xerase-j,y,ERASE);
                                 drawPixel(xdraw-j,y,ppaddle->colour);
                        }
                }
        }
        
}

void updateScore()
/* POST: updates the players score if a block has been hit (removed from sceen)
   Return: none */
{
        score += 10;    
        *pHEX7SEG = score;
}
void printScore()
{
        int tempScoreHolder1 = 0;
        int tempScoreHolder2 = 0;
        if( score < 100 && score > 0 )
        {
            tempScoreHolder1 = score / 10;
            hex7segScore = (hex7segNumbers[ tempScoreHolder1 ] << 8) + DIGIT0;
        }
        else if( score >= 100 )
        {
            tempScoreHolder1 = score / 100;
            hex7segScore = hex7segNumbers[ tempScoreHolder1 ] << 16;

            tempScoreHolder2 = ( score /10 ) - ( 10 * tempScoreHolder1 );
            hex7segScore += hex7segNumbers[ tempScoreHolder2 ] << 8;

            hex7segScore += hex7segNumbers[ 0 ];
        }
        else
            hex7segScore = DIGIT0;

        *pHEX7SEG = hex7segScore;
}

int checkkey1()
/* POST: checks if key1 has been pressed
   Return: true of false if key has been pressed */
{
        if( *pKEY & 2 )
                return TRUE;
        
        return FALSE;
}

int checkkey2()
/* POST: checks if key2 has been pressed
   Return: true of false if key has been pressed */
{
        if( *pKEY & 4 )
                return TRUE;
         
        return FALSE;
}

int checkkey3()
/* POST: checks if key3 has been pressed
   Return: true of false if key has been pressed */
{
        if( *pKEY & 8 )
                return TRUE;
        
        return FALSE;
}

void pause()
{
    while(checkkey1());   
}

void updateScreen(struct Ball* pball,struct Paddle* ppaddle,struct Block* pmobileblock,struct Block* pfixedblock ,unsigned int ERASE)
{
        int i;
        drawBall( pball, ERASE );
        pball->xinit = pball->x;
        pball->yinit = pball->y;
        //pball->count += 1;

        /*if( pball->count < 3 )
                {
                        if( pball->vyinit != pball->vy || pball->vxinit != pball->vx  )
                        {
                                pball->y += pball->vy*pball->bounce;
                                pball->x += pball->vx*pball->bounce;
                                pball->bounce -= 1/scale;
                        }
                }
        else
        {*/
                
                pball->x += pball->vx;
                pball->y += pball->vy;
                //pball->vxinit = pball->vx;
                //pball->vyinit = pball->vy;
                //pball->count = 0;
        

        /* check if collided with anything*/
        if ( collisionCheck_Paddle( pball, ppaddle, pfixedblock) )/* did it hit the paddle? if yes move ball*/
        {
                drawBall( pball, ERASE );
        }
        
        else if ( collisionCheck_Walls(pball, pfixedblock, ppaddle) )/* did it hit the wall? if yes move ball*/
        {
                drawBall( pball, ERASE );
        }

        else /* did it hit the blocks? if yes move ball*/
        {
                /* did it hit any of these blocks? if yes moveball*/
                for( i = 0; i<mobileboxOnScreen;i++ )
                {
                        /*did it hit a mobile block? If yes erase block and remove from array (so we will not check it again next time) 
                        also, move ball*/
                        if( collisionCheck_Block(pball, &pmobileblock[i],pmobileblock, ppaddle ))
                        {
                                eraseBlock( &pmobileblock[i], ERASE );
                                pmobileblock[i] = pmobileblock[mobileboxOnScreen-1];
                                mobileboxOnScreen -= 1;
                                drawBall( pball, ERASE );
                                /* update the score */
                                updateScore();
                                break;
                        }
                }

                for( i = 0; i<MAX_FBLOCKS; i++ )
                {       
                        
                        /* did it hit a fixed block? If yes move ball*/
                        if( collisionCheck_Block(pball, &pfixedblock[i], pfixedblock, ppaddle))
                        {       
                                drawBall( pball, ERASE );
                                //drawBlock(&pfixedblock[i]);
                                break;
                        }

                }

        }

        for( i = 0; i<MAX_FBLOCKS; i++ )
        {       
                drawBlock(&pfixedblock[i]);
        }
        /* erase and redraw paddle if it was moved*/
        drawPaddle( ppaddle );
        movePaddle(ppaddle,ERASE);
        timedDelay( ONE_MS * 10 );
        drawChar( 35, 40, livesRemaining + 48 );
        printScore();
            
        
        
        
}

int main( int argc, char *argv[] )
{
        /* data structures int (*arr)[8]; */
        unsigned short Acolour = makeColour(  0, 63,  0 );      /* bright green*/
        unsigned short Bcolour = makeColour( 63,  0, 63 );      /* bright magenta*/
        unsigned short Ccolour = makeColour( 30,  0, 63 );      
        unsigned short RED     = makeColour( 63,  0,  0 );      /* bright red*/
        unsigned short ERASE   = makeColour( 0,  0,  0 );      /* black*/

        int i;
        

        /*-------------------main algorithm------------------*/
        
        menuScreen();

        initialize(&paddle, pmobileBlock, pfixedBlock, &ball );
        countDown();
        while(1)
        {
                if(checkkey3())/* move paddle left */
                {
                        if(paddle.vx > 0)paddle.vx *= -1;
                }
                if(checkkey2())/* move paddle right */
                {
                        if(paddle.vx < 0)paddle.vx *= -1;
                }
                if(checkkey1())/* pause gameplay */
                {
                        pause();
                }
                if( livesRemaining == 0 )
                {
                    for( i = 0; i < sizeof(Lose) ; i++ )
                        drawChar( 15 + i, 20, Lose[i] );

                    livesRemaining = 3;
                    score = 0;
                    timedDelay( 5000 * ONE_MS );
                    printScore();
                    menuScreen();
                    initialize( &paddle, pmobileBlock, pfixedBlock, &ball );
                    
                    
                }
                if( mobileboxOnScreen == 0 )
                {
                    for( i = 0; i < sizeof(Win) ; i++ )
                        drawChar( 15 + i, 20, Win[i] );
                    
                    livesRemaining = 3;
                    score = 0;
                    timedDelay( 5000 * ONE_MS );
                    printScore();
                    menuScreen();
                    initialize( &paddle, pmobileBlock, pfixedBlock, &ball );
                }

                updateScreen(&ball,&paddle,pmobileBlock,pfixedBlock, ERASE);
        }

  return 0;
}

